package com.panda.takeaway.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.panda.takeaway.dao.*;
import com.panda.takeaway.entity.bo.CreateOrderBo;
import com.panda.takeaway.entity.bo.FoodBo;
import com.panda.takeaway.entity.bo.OrderBo;
import com.panda.takeaway.entity.dto.CommonResult;
import com.panda.takeaway.entity.dto.PageBean;
import com.panda.takeaway.entity.po.*;
import com.panda.takeaway.entity.vo.PageInfoVo;
import com.panda.takeaway.service.OrderService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xdf
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private AddressMapper addressMapper;
    @Resource
    private ShopMapper shopMapper;
    @Resource
    private BasketMapper basketMapper;
    @Resource
    private FoodMapper foodMapper;
    @Resource
    private BatchMapper batchMapper;
    @Resource
    private PhotoMapper photoMapper;

    @Override
    public CommonResult<PageBean<OrderBo>> merchantQueryOrder(OrderBo orderBo, String merchant, int page) {

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Batch> batchQueryWrapper = new QueryWrapper<>();

        List<OrderBo> orderBoList = new ArrayList<>();
        if (!"".equals(orderBo.getTele())) {
            return queryByTele(orderBo, merchant, page);
        } else {
            orderQueryWrapper.eq("order_num", orderBo.getNumber());
        }
        Order order = orderMapper.selectOne(orderQueryWrapper);
        if (order == null) {
            return CommonResult.operateFailWithMessage("找不到该订单号对应的订单");
        }
        shopQueryWrapper
                .eq("id", order.getShopId());
        Shop shop = shopMapper.selectOne(shopQueryWrapper);
        userQueryWrapper
                .eq("id", order.getUserId());
        User customer = userMapper.selectOne(userQueryWrapper);
        batchQueryWrapper
                .eq("id", order.getBatchId());
        Batch batch = batchMapper.selectOne(batchQueryWrapper);

        OrderBo orderResult = setOrderBo(customer, order, shop, batch);
        orderBoList.add(orderResult);
        PageBean<OrderBo> pageBean = new PageBean<>();
        pageBean.setTotalPage(1L);
        pageBean.setTotalCount(1L);
        pageBean.setList(orderBoList);
        return CommonResult.operateSuccess(pageBean);
    }

    @Override
    public CommonResult<PageBean<OrderBo>> merchantGetOrderByStatus(Long userId, byte status, PageInfoVo pageInfoVo) {
        List<OrderBo> orderBoList = new ArrayList<>();
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Batch> batchQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper
                .eq("user_id", userId);
        Page<Order> orderPage = new Page<>(pageInfoVo.getPage(), pageInfoVo.getSize());
        Shop shop = shopMapper.selectOne(shopQueryWrapper);
        Map<String, Object> orderMap = new HashMap<>(2);
        orderMap.put("shop_id", shop.getId());
        orderMap.put("status", status);
        orderQueryWrapper
                .allEq(orderMap);
        orderMapper.selectPage(orderPage, orderQueryWrapper);
        List<Order> orderList = orderPage.getRecords();
        PageBean<OrderBo> pageBean = new PageBean<>();
        pageBean.setTotalCount((long) orderMapper.selectList(orderQueryWrapper).size());
        pageBean.setTotalPage(pageBean.getTotalCount() + 4 / 5);
        for (Order order : orderList) {
            userQueryWrapper
                    .eq("id", order.getUserId());
            User user = userMapper.selectOne(userQueryWrapper);
            batchQueryWrapper
                    .eq("id", order.getBatchId());
            Batch batch = batchMapper.selectOne(batchQueryWrapper);
            OrderBo orderBo = setOrderBo(user, order, shop, batch);
            orderBoList.add(orderBo);
        }
        pageBean.setList(orderBoList);
        return CommonResult.operateSuccess(pageBean);
    }


    @Override
    public CommonResult<OrderBo> customerQueryOrder(Long userId, OrderBo orderBo) {
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper
                .eq("order_num", orderBo.getNumber());
        Order order = orderMapper.selectOne(orderQueryWrapper);
        if (order == null) {
            return CommonResult.operateFailWithMessage("查无该订单号对应的订单");
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper
                .eq("id", userId);
        User customer = userMapper.selectOne(userQueryWrapper);
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper
                .eq("id", order.getShopId());
        Shop shop = shopMapper.selectOne(shopQueryWrapper);
        QueryWrapper<Batch> batchQueryWrapper = new QueryWrapper<>();
        batchQueryWrapper
                .eq("id", order.getBatchId());
        Batch batch = batchMapper.selectOne(batchQueryWrapper);
        OrderBo result = setOrderBo(customer, order, shop, batch);
        return CommonResult.operateSuccess(result);
    }

    @Override
    public CommonResult<String> arrangeOrder(String number, byte status, Long userId) {
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper
                .eq("user_id", userId);
        Shop shop = shopMapper.selectOne(shopQueryWrapper);

        Map<String, Object> orderMap = new HashMap<>(2);
        orderMap.put("shop_id", shop.getId());
        orderMap.put("order_num", number);
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper
                .allEq(orderMap);
        Order order = orderMapper.selectOne(orderQueryWrapper);
        UpdateWrapper<Order> orderUpdateWrapper = new UpdateWrapper<>();
        orderUpdateWrapper
                .set("status", status)
                .allEq(orderMap);
        int result = orderMapper.update(order, orderUpdateWrapper);
        if (result != 0) {
            return CommonResult.operateSuccess();
        }
        return CommonResult.operateFailWithMessage("操作失败");
    }

    @Override
    @Transactional
    public CommonResult<String> createOrder(CreateOrderBo createOrderBo) {
        int result = 0;
        Order order = new Order();
        order.setUserId(createOrderBo.getUserId());
        order.setAddressId(createOrderBo.getAddressId());
        order.setBatchId(createOrderBo.getBatchId());
        order.setShopId(createOrderBo.getShopId());
        order.setNote(createOrderBo.getNote());
        order.setPrice(createOrderBo.getPrice());
        order.setStatus((byte) 0);
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper
                .eq("id", createOrderBo.getUserId());
        User user = userMapper.selectOne(userQueryWrapper);
        String number = localDateTime.format(dateTimeFormatter) + user.getTelephone();
        order.setOrderNum(number);
        result += orderMapper.insert(order);

        List<Long> basketList = createOrderBo.getBasketList();
        for (Long basketId : basketList) {
            QueryWrapper<Basket> basketQueryWrapper =new QueryWrapper<>();
            basketQueryWrapper
                    .eq("id",basketId);
            Basket basket = basketMapper.selectOne(basketQueryWrapper);
            UpdateWrapper<Basket> updateWrapper = new UpdateWrapper<>();
            updateWrapper
                    .set("order_id", order.getId())
                    .eq("id", basketId);
            result += basketMapper.update(basket, updateWrapper);
        }
        if (result > basketList.size()) {
            return CommonResult.operateSuccess(number);
        }
        return CommonResult.operateFailWithMessage("提交订单失败");
    }

    @Override
    public CommonResult<PageBean<OrderBo>> customerGetOrderByStatus(Long userId, byte status, PageInfoVo pageInfoVo) {
        List<OrderBo> orderBoList = new ArrayList<>();
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Batch> batchQueryWrapper = new QueryWrapper<>();

        userQueryWrapper
                .eq("id",userId);
        User customer = userMapper.selectOne(userQueryWrapper);

        Page<Order> orderPage = new Page<>(pageInfoVo.getPage(), pageInfoVo.getSize());
        Map<String, Object> orderMap = new HashMap<>(2);
        orderMap.put("user_id", userId);
        orderMap.put("status", status);
        orderQueryWrapper
                .allEq(orderMap);
        orderMapper.selectPage(orderPage, orderQueryWrapper);
        List<Order> orderList = orderPage.getRecords();
        PageBean<OrderBo> pageBean = new PageBean<>();
        pageBean.setTotalCount((long) orderMapper.selectList(orderQueryWrapper).size());
        pageBean.setTotalPage(pageBean.getTotalCount() + 4 / 5);
        for (Order order : orderList) {
            shopQueryWrapper
                    .eq("id", order.getShopId());
            Shop shop = shopMapper.selectOne(shopQueryWrapper);
            batchQueryWrapper
                    .eq("id", order.getBatchId());
            Batch batch = batchMapper.selectOne(batchQueryWrapper);
            OrderBo orderBo = setOrderBo(customer, order, shop, batch);
            orderBoList.add(orderBo);
        }
        pageBean.setList(orderBoList);
        return CommonResult.operateSuccess(pageBean);
    }

    /**
     * 根据手机号查找订单
     *
     * @param orderBo  包含手机号
     * @param merchant 商家账号
     * @param page     分页信息
     * @return
     */
    private CommonResult<PageBean<OrderBo>> queryByTele(OrderBo orderBo, String merchant, int page) {
        List<OrderBo> orderBoList = new ArrayList<>();

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        QueryWrapper<User> merchantQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();

        /**
         * 查找商家对应的shop
         */
        merchantQueryWrapper
                .eq("telephone", merchant);
        User merchantUser = userMapper.selectOne(merchantQueryWrapper);
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper
                .eq("user_id", merchantUser.getId());
        Shop shop = shopMapper.selectOne(shopQueryWrapper);

        /**
         * 查找手机号对应的用户
         */
        userQueryWrapper.eq("telephone", orderBo.getTele());
        User customer = userMapper.selectOne(userQueryWrapper);

        if (customer == null) {
            return CommonResult.operateFailWithMessage("找不到该号码对应用户");
        }

        /**
         * 根据用户id和店铺id查找订单列表
         */
        Map<String, Object> orderMap = new HashMap<>(2);
        orderMap.put("user_id", customer.getId());
        orderMap.put("shop_id", shop.getId());
        orderQueryWrapper
                .allEq(orderMap);
        Page<Order> orderPage = new Page<>(page, 5);
        orderMapper.selectPage(orderPage, orderQueryWrapper);
        List<Order> orderList = orderPage.getRecords();
        PageBean<OrderBo> pageBean = new PageBean<>();
        pageBean.setTotalCount((long) orderMapper.selectList(orderQueryWrapper).size());
        pageBean.setTotalPage(pageBean.getTotalCount() + 4 / 5);
        for (Order order : orderList) {
            QueryWrapper<Batch> batchQueryWrapper = new QueryWrapper<>();
            batchQueryWrapper
                    .eq("id", order.getBatchId());
            Batch batch = batchMapper.selectOne(batchQueryWrapper);
            OrderBo orderResult = setOrderBo(customer, order, shop, batch);
            orderBoList.add(orderResult);
        }
        pageBean.setList(orderBoList);
        return CommonResult.operateSuccess(pageBean);
    }

    /**
     * 封装返回给前端的订单信息
     *
     * @param customer 订单顾客
     * @param order    订单
     * @param shop     店铺
     * @return
     */
    private OrderBo setOrderBo(User customer, Order order, Shop shop, Batch batch) {
        List<FoodBo> foodBoList = new ArrayList<>();

        QueryWrapper<Basket> basketQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Address> addressQueryWrapper = new QueryWrapper<>();

        OrderBo orderResult = new OrderBo();
        orderResult.setDeliveryTime(batch.getDeliveryTime());
        orderResult.setTele(customer.getTelephone());
        orderResult.setNumber(order.getOrderNum());
        orderResult.setTotalPrice(order.getPrice());
        orderResult.setStatus(order.getStatus());
        orderResult.setCreateTime(order.getCreateTime());
        orderResult.setNote(order.getNote());
        orderResult.setShopName(shop.getShopName());
        addressQueryWrapper.eq("id", order.getAddressId());
        Address address = addressMapper.selectOne(addressQueryWrapper);
        orderResult.setAddress(address);
        basketQueryWrapper
                .eq("order_id", order.getId());
        List<Basket> basketList = basketMapper.selectList(basketQueryWrapper);
        for (Basket basket : basketList) {
            FoodBo foodBo = new FoodBo();
            foodBo.setPrice(basket.getTotalPrice());
            foodBo.setSum(basket.getNum());

            QueryWrapper<Food> foodQueryWrapper = new QueryWrapper<>();
            foodQueryWrapper
                    .eq("id", basket.getFoodId());
            Food food = foodMapper.selectOne(foodQueryWrapper);
            foodBo.setFoodName(food.getFoodName());

            QueryWrapper<Photo> photoQueryWrapper = new QueryWrapper<>();
            photoQueryWrapper.eq("id", food.getPhotoId());
            Photo photo = photoMapper.selectOne(photoQueryWrapper);
            foodBo.setPhotoAddress(photo.getUrl());
            foodBoList.add(foodBo);
        }
        orderResult.setFoodList(foodBoList);
        return orderResult;
    }
}
